package centerberg.engine;

import java.awt.Shape;

/**
 * The base class for any rigid bodies simulated by the physics engine.
 * 
 * @author Andreas Svanberg
 */
public abstract class RigidBody extends PhysicsObject
{
    private Vector velocity;
    private Vector force;
    private double mass;
    /**
     * Determines how bouncy the body is. 1 being completely elastic and
     * 0 being no bouncing at all.
     */
    private double bounciness;
    
    /**
     * Creates a new rigid body with no velocity, force, or mass.
     */
    protected RigidBody(Shape shape)
    {
        super(shape);
        
        velocity = new Vector(0.0, 0.0);
        force = new Vector(0.0, 0.0);
        mass = 0;
        bounciness = 0;
    }
    
    /**
     * Adds force to the object.
     * 
     * @param v the force to add
     */
    public void addForce(Vector v)
    {
        force = force.add(v);
    }
    
    /**
     * Adds velocity to the object.
     * 
     * @param v the velocity to add
     */
    public void addVelocity(Vector v)
    {
        velocity = velocity.add(v);
    }
    
    /**
     * Returns the bounciness of the object. The bounciness determines how
     * much force is lost from the normal vector when colliding.
     * 
     * @return the bounciness
     */
    public double getBounciness()
    {
        return bounciness;
    }
    
    /**
     * Returns the 2-dimensional vector with the objects current force.
     * 
     * @return a 2-dimensional vector with forces
     */
    public Vector getForce()
    {
        return force;
    }
    
    /**
     * Returns the mass of the object.
     * 
     * @return the mass of the object
     */
    public double getMass()
    {
        return mass;
    }
    
    /**
     * Returns the 2-dimensional vector with the objects current velocity.
     * 
     * @return a 2-dimensional vector with velocity
     */
    public Vector getVelocity()
    {
        return velocity;
    }
    
    /**
     * Updates the bounciness of this object.
     * 
     * @param bounciness the new bounciness in the range [0, 1]
     * @throws IllegalArgumentException if bounciness is outside range [0, 1]
     */
    public void setBounciness(double bounciness)
    {
        if (bounciness < 0 || bounciness > 1)
            throw new IllegalArgumentException("Bounciness range expected: [0, 1], got: " + bounciness);
        this.bounciness = bounciness;
    }
    
    /**
     * Updates the objects force.
     * 
     * @param force the new force
     */
    public void setForce(Vector force)
    {
        this.force = force;
    }
    
    /**
     * Updates the objects mass.
     * 
     * @param mass the new mass
     */
    public void setMass(double mass)
    {
        this.mass = mass;
    }
    
    /**
     * Updates the objects velocity.
     * 
     * @param velocity the new velocity
     */
    public void setVelocity(Vector velocity)
    {
        this.velocity = velocity;
    }
}
